package com.yc.starter.login.biz;

import com.yc.starter.login.LoginProperties;
import com.yc.starter.login.util.Utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.lang.reflect.Field;
import java.util.Map;

@Service
public class AuthBiz {

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Autowired
    LoginProperties properties;

    public Object login(String username, String password){
        // 验证
        Utils.checkEmpty(username, "账号不能为空")
                .checkEmpty(password, "密码不能为空")
                .check(username.length()<2, "账号长度不能小于2")
                .check(password.length()<6, "密码长度不能小于6");

        // 动态拼接sql
        String sql = "select *" +
                "  from " + properties.getUserTable() +
                " where " + properties.getUsernameColumn() + " = ?" +
                "   and " + properties.getPasswordColumn() + " = ?";
        // md5加密
        if("md5".equals(properties.getEncryption())){
            password = DigestUtils.md5DigestAsHex((username + password).getBytes());
        }
        System.out.println("password = " + password);
        // 执行查询
        Object ret = null;
        try{
            if(properties.getUserClass() == null){
                ret = jdbcTemplate.queryForMap(sql,username,password);
                ((Map<String, Object>) ret).put(properties.getPasswordColumn(),null);
            } else {
                // 查询结果封装为一个实体对象
                ret = jdbcTemplate.queryForObject(sql,
                        // 封装为实体对象
                        new BeanPropertyRowMapper<>(properties.getUserClassObject()),
                        username,password);
                // 清空密码字段
                Field field = ret.getClass().getDeclaredField(properties.getPasswordColumn());
                field.setAccessible(true);
                field.set(ret,null);
                // TODO 请转换邮箱字段中间几个字符为*
            }
        } catch (DataAccessException e) {
            // mybatis 查询一个对象时, 如果没有查询到数据, 返回是 null
            // spring 查询一个对象时, 如果没有查询到数据, 是抛出异常
            throw new BizException("用户名或密码错误",e);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new RuntimeException("密码字段清空失败", e);
        }
        return ret;
    }

    @Autowired
    private JavaMailSender mailSender;
    @Value("${login.mail.fromMail.addr}")
    private String from;

    public String forgetPwd(String username){
        Utils.checkEmpty(username, "账号不能为空")
                .check(username.length()<2, "账号长度不能小于2");

        // 校验账号是否存在
        String sql = "select " + properties.getEmailColumn() +
                " from " + properties.getUserTable() +
                " where " + properties.getUsernameColumn() + " = ?";
        try{
            String email = jdbcTemplate.queryForObject(sql, String.class, username);
            // 发送邮件
            SimpleMailMessage message = new SimpleMailMessage();
            message.setFrom(from);
            message.setTo(email);
            message.setSubject("密码重置验证码");
            String code = System.currentTimeMillis() + "";
            code = code.substring(code.length() - 4);
            message.setText("您的密码重置链接为: " + code);
            mailSender.send(message);
            return code;
        } catch (DataAccessException e) {
            throw new BizException("账号不存在", e);
        }
    }

    public void resetPwd(String username, String pwd, String repwd){
        Utils.checkEmpty(username, "账号不能为空")
                .checkEmpty(pwd, "密码不能为空")
                .check(pwd.length()<6, "密码长度不能小于6")
                .checkEmpty(repwd, "确认密码不能为空")
                .check(!pwd.equals(repwd), "两次密码不一致");
        String sql = "update " + properties.getUserTable() +
                " set " + properties.getPasswordColumn() + " = md5(concat(?,?))" +
                " where " + properties.getUsernameColumn() + " = ?";
        jdbcTemplate.update(sql, username, pwd, username);
    }

}
